package controllers;

import models.Component;

import models.ComponentUser;
import models.DemoEntry;
import models.Event;
import models.Log;
import models.Notification;
import models.User;
import models.UserStory;
import models.Project;
import notifiers.Mails;

import java.util.*;

import play.mvc.Controller;
import play.mvc.With;


/**
 * @author mohamedhisham, salma_hamed
 *
 */
@With(Secure.class)
public class ProductBacklog extends Controller {
	/**
	 * 
	 * @param storyID
	 * 		the userStory id
	 * @return
	 * 		true if this userStroy is in a sprint today
	 */
	public static boolean storyCurrentlyInSprint(long storyID){
		UserStory story=UserStory.findById(storyID);
		List<Event> storyEvent=story.events;
		boolean inSprint=false;
		for(int i=0;i<storyEvent.size();i++){
			if(Events.sprintInProgress((Long) storyEvent.get(i).getEntityId())){
				inSprint=true;
				
			}
			else{
				inSprint=false;
			}
		}
		
		return inSprint;
	}
	/**
	 * This method checks if the developer is member of this component 
	 * @param compid
	 * 	 this is the component ID
	 * @return
	 */
	public static boolean isMember(final long compid){
		boolean mem= false;
		long userId = Long.parseLong(session.get("userId"));
		Component comp = Component.findById(compid);
		for(int i=0;i<comp.user_components.size();i++)
			if((Long)comp.user_components.get(i).user.getEntityId()==userId)
				mem=true;
		return mem;
		}
		/**
		 * this story associate to a user story a new component to depend on
		 * @param id
		 *  the id of the user story i am adding to it
		 * @param proid
		 * 	the project id 
		 * @param newcomp
		 *  the new component entered to let the user story added to it
		 * @return
		 */
	 public static boolean addDepend(final long id,final long proid , final String newcomp) {
	       Component comp = Component.find("byName", newcomp).first();
	       long userId = Long.parseLong(session.get("userId"));
	       User inSession=User.findById(userId);
	       UserStory edit = UserStory.findById(id);
	       Project p = Project.find("byId", proid).first();
	       List<Component> component = new LinkedList<Component>();
	       component = p.components;
	       boolean avalible = false;
	       for (int i = 0; i < component.size(); i++) {
	              if (newcomp.equals(component.get(i).name)) {
	                  comp = component.get(i);
	                  avalible = true;
	              }
	       }
	       if (comp!=null && avalible) {
	    	   if(!edit.dependOnComponents.contains(comp)){
	          edit.dependOnComponents.add(comp);
	          new Log(userId, (Long) edit.getEntityId(), "UserStory", "Added a component DependOn",
	  				proid, " ").save(); 
	          if((Long)edit.getEntityId()==userId){
	          new Notification((Long) edit.creator.id,
	  				"Edit in User Story" , inSession.userName + "Added Depend On component in Story :-"+edit.story)
	  				.save();
	  		Mails.editPB(edit.creator,inSession.userName + "Added Depend On component in Story :-"+edit.story,
	  				"Edit in User Story");
	          }
	    	   }
	    	   else
	    		   flash.error("The story depends on this component already");   
	       }
	       else
	    	   flash.error("This value is invalid");
	        edit.save();
	        return true;
	     }
	 /**
	  * this method deletes the component this story depends on
	  * @param id
	  *  the id of the userstory
	  * @param oldcomp
	  * 
	  * @param proid
	  * 
	  * @return
	  */
	 public static boolean deleteDep(final long id, final String oldcomp,final long proid){
		 long userId = Long.parseLong(session.get("userId"));
		 User inSession=User.findById(userId);
		 Component old = Component.find("name",oldcomp).first();
         UserStory edit = UserStory.findById(id);
         new Log(userId, (Long) edit.getEntityId(), "UserStory", "Deleted a component DependOn",
   				proid, " ").save(); 
         if((Long)edit.getEntityId()==userId){
         new Notification((Long) edit.creator.id,"Edit in User Story" , 
        		 inSession.userName + "Deleted"+ old.name +"Depend On component in Story :-"+edit.story)
	  				.save();
         Mails.editPB(edit.creator,inSession.userName + "Deleted"+ old.name +"Depend On component in Story :-"+edit.story,
			"Edit in User Story");
         }
         edit.dependOnComponents.remove(old);
         edit.save();
         return true;
	 }
    /**
     * @param id
     *          the user story id we editing in it
     * @param compid
     *          the id of the component going to be changed
     * @param proid
     *        takes the project id to make sure the new depend component belongs
     *        to the project
     * @param newcomp
     *      the name of the new component name
     */
      public static boolean editdependency(final long id, final String oldcomp,
               final long proid , final String newcomp) {
    	 long userId = Long.parseLong(session.get("userId"));
    	 User inSession=User.findById(userId);
         Component comp = Component.find("byName", newcomp).first();
        
         Component old = Component.find("name",oldcomp).first();
         UserStory edit = UserStory.findById(id);
         Project p = Project.find("byId", proid).first();
         List<Component> component = new LinkedList<Component>();
         component = p.components;
         boolean avalible = false;
         for (int i = 0; i < component.size(); i++) {
                if (newcomp.equals(component.get(i).name)) {
                    comp = component.get(i);
                    avalible = true;
                }
         }
         if (comp!=null && avalible) {
        	 if(!edit.dependOnComponents.contains(comp)){
            edit.dependOnComponents.add(comp);
            edit.dependOnComponents.remove(old);
            new Log(userId, (Long) edit.getEntityId(), "UserStory", "Edit the component DependOn",
    				proid, " ").save();
            if((Long)edit.getEntityId()==userId){
            new Notification((Long) edit.creator.id,"Edit in User Story" , 
           		 inSession.userName + "Edited"+ old.name +"Depend On component in Story :-"+edit.story+"to component"+comp.name)
   	  				.save();
            Mails.editPB(edit.creator,inSession.userName + "Edited"+ old.name +"Depend On component in Story :-"+edit.story+"to component"+comp.name,
			"Edit in User Story");
        	 }
        	 }
        	 else
        		 flash.error("The Story already depends on this component");
         }
         else
        	 flash.error("Invalid input");
          edit.save();
          return true;
       }
   
    /**
     * @param storyId
     *       the story id from the view page to know
     *       which story to edit its properties
     * @param newValue
     *            the new value brought from the edit section of the script
     *            and passed to this method sets the new value
     *            to the notes of this UserStory
     *            and saves it in the database.
     */
     public static boolean editNotes(final long storyId,
            final String newValue,final long proid) {
    	 long userId = Long.parseLong(session.get("userId"));
        UserStory edit = UserStory.findById(storyId);
        User inSession=User.findById(userId);
        edit.note = newValue;
        new Log(userId, (Long) edit.getEntityId(), "UserStory", "Edit the User Story Notes",
				proid, " ").save();
        if((Long)edit.getEntityId()==userId){
        new Notification((Long) edit.creator.id,"Edit in User Story" , 
       		 inSession.userName + "Changed note in Story :-"+edit.story)
	  				.save();
        Mails.editPB(edit.creator,inSession.userName + "Changed note in Story :-"+edit.story,
		"Edit in User Story");
        }
        edit.save();
        return true;
     }

    /**
     * @param storyId
     *          the story id from the view page to know
     *          which story to edit its properties
     * @param newValue
     *            the new value brought from the edit section of the script
     *            and passed to this method sets the new value
     *            to the estimate points of this UserStory
     *            and saves it in the database.
     */
     public static boolean editPoint(final long storyId,
            final double newValue,final long proid) {
    	 
    	 long userId = Long.parseLong(session.get("userId"));
        UserStory edit = UserStory.findById(storyId);
        edit.effortEstimation = newValue;
        new Log(userId, (Long) edit.getEntityId(), "UserStory", "Edit the User Story Point",
				proid, " ").save();
        User inSession=User.findById(userId);
        if((Long)edit.getEntityId()==userId){
        new Notification((Long) edit.creator.id,"Edit in User Story" , 
          		 inSession.userName + "Changed Estimate Points for Story :-"+edit.story)
   	  				.save();
        Mails.editPB(edit.creator, inSession.userName + "Changed Estimate Points for Story :-"+edit.story,
		"Edit in User Story");
        }
        edit.save();
        return true;
     }

    /**
     *@param storyId
     *            the story id from the view page to know
     *            which story to edit its properties
     *@param newValue
     *            the new value brought from the edit section of the script
     *            and passed to this method sets the new value
     *            to the story of this UserStory
     *            and saves it in the database.
     */
     public static boolean editDesc(final long storyId, final String newValue,final long proid,final String oldValue) {
    	 
    	 long userId = Long.parseLong(session.get("userId"));
    	 User inSession=User.findById(userId);
    	 String old = oldValue;
    	 
        UserStory edit = UserStory.findById(storyId);
       
        edit.story = newValue;
        edit.save();
        new Log(userId, (Long) edit.getEntityId(), "UserStory", "Edit the User Story Description",
				proid, " ").save();
        if((Long)edit.getEntityId()==userId){
        new Notification((Long) edit.creator.id,"Edit in User Story" , 
         		 inSession.userName + "Changed Description of the Story from :-"+old+ "to"+edit.story)
  	  				.save();
        Mails.editPB(edit.creator, inSession.userName + "Changed Description of the Story from :-"+old+ "to"+edit.story,
		"Edit in User Story");
        }
       return true;
    }
    /**
     * @param dId
     * 			the demo id from the view page to know
     *            which demo to edit it
     * @param newValue
     *           the new value brought from the edit section of the script
     *            and passed to this method sets the new value
     *            to the demo of this UserStory
     *            and saves it in the database.
     */
     public static boolean editDemo(final long dId, final String newValue,final long proid) {
    	 long userId = Long.parseLong(session.get("userId"));
    	 User inSession=User.findById(userId);
        DemoEntry edit = DemoEntry.findById(dId);
        edit.demo = newValue;
        
        new Log(userId, (Long) edit.getEntityId(), "UserStory", "Edit the User Story Demo",
				proid, " ").save();
        if((Long)edit.getEntityId()==userId){
        new Notification((Long) edit.userStory.creator.id,"Edit in User Story" , 
         		 inSession.userName + "Changed Demo for Story :-"+edit.userStory.story)
  	  				.save();
        Mails.editPB(edit.userStory.creator, inSession.userName + "Changed Demo for Story :-"+edit.userStory.story,
		"Edit in User Story");
        }
        edit.save();
        return true;
    }

    /**
     * @param projectID
     *            takes the project id as input to view
     *            the product backlog of this project,
     *            renders this project component list, all the
     *            success and failure demos.
     */

     public static void viewBacklog(final Long projectID) {
    	Security.checkAccess("View the project backlog", projectID, Project.class
 	            .getName());
        Project pro = Project.find("byId", projectID).first();
        List<Component> pComponents;
        List<DemoEntry> alldemos = DemoEntry.all().fetch();
        List<DemoEntry> sdemo = new LinkedList<DemoEntry>();
        List<DemoEntry> fdemo = new LinkedList<DemoEntry>();
        if (pro.components.isEmpty()) {
            render("There is no project with this id entered");
            // if empty components->empty product backlog appears
        } else {
            pComponents = pro.components;
            for (int i = 0; i < alldemos.size(); i++) {
                if (alldemos.get(i).type == true) {
                     sdemo.add(alldemos.get(i));
                } else {
                    if (alldemos.get(i).type == false) {
                        fdemo.add(alldemos.get(i));
                    }
                }
             }
             render(projectID, pComponents, fdemo, sdemo, pro);
        }
     }
   
}
